using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using MapEditor;
using System.Configuration;
using System.IO;

namespace MapEditor
{
    public partial class mainForm : Form
    {
        public bool MovingPicture;
        public bool MouseIsDown;
        private int OffsetX, OffsetY;
        public int PlayerID =0;

        public int PreviousMouseX = 0;
        public int PreviousMouseY = 0;

        //defines the main map image bitmap
        public Image mapImage;
        public Map myMap;

        //public Graphics FrontBuffer;
        //public Graphics BackBuffer;
        //public Bitmap TempBuffer;
        public Game Game;


        public mainForm()
        {
            InitializeComponent();
            myMap = new Map();
            this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true); 
        }

        private void btnSave_Click(object sender, EventArgs e)
            //save the map - TODO get this working
        {
            //bool MapSaved;


            string SaveLocation = this.txtSaveLocation.Text;
            string MapName = this.txtMapName.Text;
            Map ccMap = new Map();
            ccMap.Name = MapName;
            //GameGraphics FMMap = new GameGraphics();



            ccMap = (Map)myMap;
            //FMMap.Map = ccMap;

            System.Xml.Serialization.XmlSerializer writer = new System.Xml.Serialization.XmlSerializer(typeof(Map));
            System.IO.Stream fs = new FileStream("c:\\testmap.xml", FileMode.Create);
            writer.Serialize(fs, Game.GraphicsEngine.Map);
            //fs.Close();



            //MapSaved = ccMap.CreateMapTiles(SaveLocation);

            //if (!MapSaved)
            //{
            //    MessageBox.Show("Could not save map.");
            //}
            //else
            //{
            //    MessageBox.Show("Map saved to : " + SaveLocation + MapName);

            //}

            
        }

        //Mouse picture controls
        private void picMap_OnMouseDown(object sender, MouseEventArgs e)
        {
                //Application.DoEvents();

            PreviousMouseX = e.X;
            PreviousMouseY = e.Y;
            OffsetX = 0; OffsetY = 0;
            //get the element for this x and y
            int GameX = e.X + Game.GraphicsEngine.XOffset;
            int GameY = e.Y + Game.GraphicsEngine.YOffset;


            //which mouse button?
            if (e.Button == MouseButtons.Right)
            {
                int ElementID;
                int ElevationValue;

                ElementID = (int)Game.GraphicsEngine.Map.TerrainArray.GetValue(((GameX) / 10), ((GameY) / 10));
                lblElementType.Text = Game.GraphicsEngine.Map.TerrainElement(ElementID);
                ElevationValue = (int)Game.GraphicsEngine.Map.ElevationArray.GetValue(((GameX) / 10), ((GameY) / 10));
                lblElevation.Text = (string)"" + ElevationValue;

                MovingPicture = true;
            }



            if (e.Button == MouseButtons.Left)
            {
                if (Game.GivingOrder)
                {
                    Squad currentSquad;
                    currentSquad = (Squad)Game.Companies[PlayerID].Squads[Game.Companies[PlayerID].CurrentlySelectedSquad];
                    int SquadID = Game.Companies[PlayerID].CurrentlySelectedSquad;

                    Game.GiveOrder(Game.PlayerID,currentSquad.Order.NextOrder,SquadID, GameX, GameY);
                }
                else
                {
                    int currentSquad = Game.SelectSquad(GameX, GameY);
                    if (currentSquad != -1)
                    {
                        Game.Companies[PlayerID].CurrentlySelectedSquad = currentSquad;

                    }
                    else
                    {

                        Game.Companies[PlayerID].CurrentlySelectedSquad = -1;
                    }
                }




            
            }


        }





        private void picMap_OnMouseUp(object sender, MouseEventArgs e)
        {
            MovingPicture = false;
            MouseIsDown = false;
        }

        private void picMap_OnMouseMove(object sender, MouseEventArgs e)
        {
            if (MovingPicture==true)
            {
                int MouseX, MouseY;
                MouseX = e.X;
                MouseY = e.Y;

                OffsetX += MouseX - PreviousMouseX;
                OffsetY += MouseY - PreviousMouseY;

                PreviousMouseX = MouseX;
                PreviousMouseY = MouseY;

            }

            if (Game != null)
            {
                int CurrentSquad = Game.Companies[Game.PlayerID].CurrentlySelectedSquad;
                if (CurrentSquad!=-1)
                {
                    if (Game.Companies[Game.PlayerID].Squads[CurrentSquad].Order.NextOrder ==Order.OrderType.Move)
                    {
                        //draw a line
                        Squad mySquad = new Squad();
                        mySquad = (Squad)Game.Companies[Game.PlayerID].Squads[CurrentSquad];
                        int SquadLeader = mySquad.SquadLeader;

                        Game.GraphicsEngine.DrawLine
                            (
                                new Point(
                                            mySquad.Soldiers[SquadLeader].X - Game.GraphicsEngine.XOffset 
                                               - mySquad.Soldiers[SquadLeader].SoldierImage.Center.X + 4,
                                            mySquad.Soldiers[SquadLeader].Y - Game.GraphicsEngine.YOffset 
                                               - mySquad.Soldiers[SquadLeader].SoldierImage.Center.Y + 4
                                         ), 
                                new Point(  e.X, e.Y)
                            );
                        mySquad = null;

                    }

                }
            }




        }

        private void mainForm_Load(object sender, EventArgs e)
        {

        }

        #region scrollbar stuff - TODO remove
        public void DisplayScrollBars()
        {
            // If the image is wider than the PictureBox, show the HScrollBar.
            if (picMap.Width > picMap.Image.Width - this.vScrollBar1.Width)
            {
                hScrollBar1.Visible = false;
            }
            else
            {
                hScrollBar1.Visible = true;
            }

            // If the image is taller than the PictureBox, show the VScrollBar.
            if (picMap.Height >
                picMap.Image.Height - this.hScrollBar1.Height)
            {
                vScrollBar1.Visible = false;
            }
            else
            {
                vScrollBar1.Visible = true;
            }
        }

        private void HandleScroll(Object sender, ScrollEventArgs se)
        {
            //Application.DoEvents();

            //Game.GraphicsEngine.UpdateMap(hScrollBar1.Value, vScrollBar1.Value);
            lblMouseX.Text = hScrollBar1.Value.ToString();
            lblMouseY.Text = vScrollBar1.Value.ToString();
            //DrawStuff();

            lblMapX.Text = Convert.ToString(hScrollBar1.Value);
            lblMapY.Text = Convert.ToString(vScrollBar1.Value);

        }

        public void SetScrollBarValues()
        {
            // Set the Maximum, Minimum, LargeChange and SmallChange properties.
            this.vScrollBar1.Minimum = 0;
            this.hScrollBar1.Minimum = 0;

            // If the offset does not make the Maximum less than zero, set its value. 
            if ((this.picMap.Image.Size.Width - picMap.ClientSize.Width) > 0)
            {
                this.hScrollBar1.Maximum =
                    this.picMap.Image.Size.Width - picMap.ClientSize.Width;
            }

            this.hScrollBar1.LargeChange = this.hScrollBar1.Maximum / 10;
            this.hScrollBar1.SmallChange = this.hScrollBar1.Maximum / 20;



            // If the offset does not make the Maximum less than zero, set its value.    
            if ((this.picMap.Image.Size.Height - picMap.ClientSize.Height) > 0)
            {
                this.vScrollBar1.Maximum =
                    this.picMap.Image.Size.Height - picMap.ClientSize.Height;
            }


            this.vScrollBar1.LargeChange = this.vScrollBar1.Maximum / 10;
            this.vScrollBar1.SmallChange = this.vScrollBar1.Maximum / 20;


        }
        #endregion





        private void DoStuff()
        {
            //stop the spinning!
            //for (int looper = 0; looper < Game.Squad.Soldiers.Length; looper++)
            //{
            //    Game.Squad.Soldiers[looper].Angle += 45;
            //}

            Game.DoThinking();

        }


        private void btnConvert_Click(object sender, EventArgs e)
        {




            Map ccMap = new Map();
            ccMap = (Map)myMap;
            ccMap.Name = txtMapName.Text;
            
            string mapFile = txtFileLocation.Text + txtMapName.Text;
            //load the roof information
            ccMap.Roofs = (Roofs)CC.LoadRoofInformation(mapFile + ".RFM");
            //load and convert the BGM
            ccMap.BaseImage = CC.ConvertCCMapToIMage(mapFile + ".BGM");

            //load and convert the OVM
            ccMap.OverviewImage = CC.ConvertCCMapToIMage(mapFile + ".OVM");
            //load and convert the MMM
            ccMap.ThumbnailImage = CC.ConvertCCMapToIMage(mapFile + ".MMM");
            //Load and convert the Elevations
            ccMap.ElevationArray = CC.LoadTerrain(mapFile + ".TXT", ref ccMap, CC.TerrainType.Elevation);
            //Load and convert the Elements
            ccMap.TerrainArray = CC.LoadTerrain(mapFile + ".TXT", ref ccMap, CC.TerrainType.Terrain);
            //load the terrain element descriptions to make sense of the terrain array
            ccMap.TerrainElements = (TerrainElements.Terrain[])CC.LoadTerrainElementsFromFile("C:\\Graphics\\Maps\\Data\\Elements.xml");



            //load the image into the picturebox and load the thumbnail

            //this.picMap.ImageLocation  = txtFileLocation.Text;
            this.picMap.Image = ccMap.BaseImage;
            this.picThumbnail.Image = ccMap.ThumbnailImage;

            //load the dimensions of the image
            lblIMageXPix.Text = ccMap.Width.ToString();
            lblIMageYPix.Text = ccMap.Height.ToString();

            //display the scrollbars, if needed
            this.DisplayScrollBars();
            this.SetScrollBarValues();
            this.Refresh();

            CreateGame(ccMap);
            
            //Complete!
            MessageBox.Show("Map:" + ccMap.Name + " loaded.");


        }

        private void CreateGame(Map ccMap)
        {
            Game = new Game();
            Game.GraphicsEngine.Map = ccMap;
            Game.GraphicsEngine.ImageWidth = picMap.Width;
            Game.GraphicsEngine.ImageHeight = picMap.Height;
            Game.GraphicsEngine.CreateBuffers();
            Game.GraphicsEngine.CreateBaseMap();
            Game.PlayerID = 0;

            //create a new squad TODO change this to creating an army of squads for multiple players
            Game.CreateCompanies(1);

        }



        private void btnCreateSoldier_Click(object sender, EventArgs e)
        {

        }

        private void tmGameTick_Tick(object sender, EventArgs e)
        {

                //do game stuff
                Timer timer = new Timer();
                timer.StartTimer();
                if (Game != null)
                {

                        //Application.DoEvents();
                        DrawStuff();

                }
                timer.StopTimer();

                //show the time to do a loop
                lblTimer.Text = lblTimer.Text.Replace("Time to render:", "");
                lblTimer.Text = "Time to render: " + timer.Time.ToString();



        }


        private void DrawStuff()
        {
            /* Create a graphics object and draw a portion 
       of the image in the PictureBox. */

            Timer timer = new Timer();

            timer.StartTimer();

            if (MovingPicture)
            {
                if (  ((OffsetX != 0) && (OffsetY != 0)) && (  (Math.Abs(OffsetX)>1)  ||  (Math.Abs(OffsetY)>1))  )
                {
                    Game.GraphicsEngine.UpdateMap(Game.GraphicsEngine.XOffset - OffsetX, Game.GraphicsEngine.YOffset - OffsetY);
                    OffsetX = 0;
                    OffsetY = 0;
                    timer.StopTimer();
                }


            }



            


            //Application.DoEvents();

            timer.StartTimer();
            Game.GraphicsEngine.CreateBaseMap();
            timer.StopTimer();
            //Application.DoEvents();

            timer.StartTimer();
            Game.GraphicsEngine.DrawSoldiers(Game.Companies);
            timer.StopTimer();
            //Application.DoEvents();

            picMap.Image = Game.GraphicsEngine.GetScreen();
            //Application.DoEvents();

        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            //do game stuff
            Timer timer = new Timer();
            timer.StartTimer();
            if (Game != null)
            {
                //Application.DoEvents();
                DoStuff();

            }
            timer.StopTimer();
        }

        private void mainForm_KeyDown(object sender, KeyEventArgs e)
        {
            //we have pressed a key!
            int CurrentSquad = Game.Companies[Game.PlayerID].CurrentlySelectedSquad;
            if (CurrentSquad!=-1)
            {
                //we have a squad selected, so we're trying to give an order
                //lblMisc.Text = e.KeyCode.ToString();

                string KeyPress = e.KeyCode.ToString();

                switch (KeyPress)
                {
                    case "B":
                        Game.Companies[Game.PlayerID].Squads[CurrentSquad].Order.NextOrder= Order.OrderType.Hide;
                        Game.GivingOrder = true;
                        lblMisc.Text = "Hiding";

                        Squad mySquad;
                        mySquad = (Squad)Game.Companies[PlayerID].Squads[CurrentSquad];
                        Game.GiveOrder(Game.PlayerID, mySquad.Order.NextOrder, CurrentSquad, 0, 0);

                        break;
                    case "X":
                        Game.Companies[Game.PlayerID].Squads[CurrentSquad].Order.NextOrder = Order.OrderType.Move;
                        Game.GivingOrder = true;
                        lblMisc.Text = "Moving";
                        break;
                    case "N":
                        Game.Companies[Game.PlayerID].Squads[CurrentSquad].Order.NextOrder = Order.OrderType.TurnToFace;
                        Game.GivingOrder = true;
                        lblMisc.Text = "Turning To Face (Defend)";


                        break;
                    default:
                        lblMisc.Text = "No Order - continuing with Previous";
                        Game.GivingOrder = false;
                        break;
                }

            }
        }



      

  






    }
}